/**
 * 
 */
package org.vectrics.recruiter.struts.tag;

/**
 * @author gvilla
 * 
 */

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Category;
import org.vectrics.DataException;
import org.vectrics.SystemException;
import org.vectrics.common.util.StringUtils;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.location.Location;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.VectricsTagSupport;

public class StrictLocationComboTag extends VectricsTagSupport {
    static private Category log = Category.getInstance(LocationComboTag.class);

    private String styleClass = null;

    private String property = null;

    private String selected = null;

    private String none = "false";

    private String showIndents = "true";

    private String domainId = null;

    private String locationType = null;

    public StrictLocationComboTag() {
        super();
    }

    @Override
    public String makeStartTag() {
        StringBuffer html = new StringBuffer();

        log.debug("doStartTag() called");
        HttpServletRequest request = (HttpServletRequest) super.pageContext.getRequest();
        // String contextPath = request.getContextPath();

        if (selected == null && property != null) {
            selected = request.getParameter(property);
        }

        if (log.isDebugEnabled()) {
            log.debug("doStartTag() - selected = " + selected);
        }

        if (styleClass == null) {
            html.append("<select name=\"" + property
                    + "\" style=\"width:250;font-family:verdana,arial,sans serif;font-size=" + "11px\">");
        } else {
            html.append("<select name=\"" + property + "\" class=\"" + styleClass + "\">");
        }

        if (none.toLowerCase().startsWith("t")) {
            html.append("<option value=\"\"></option>");
        }

        try {
            Domain domain = getDomain();
            if (domain == null)
                throw new SystemException("Could not find domain: " + getDomainId());

            List<Location> allLocations = CoreServiceLocator.getLocationService().findAllLocations(domain,
                    getLocationType());
            Iterator<Location> iter = allLocations.iterator();
            while (iter.hasNext()) {
                Location location = iter.next();
                if (Location.COUNTRY.equals(location.getTypeCode())) {
                    displayLocation(html, location, 0, allLocations);
                }
            }
        } catch (Exception de) {
            log.error("Exception finding locations", de);
            throw new DataException("Exception finding locations", de);
        }
        html.append("</select>");
        return html.toString();
    }

    private void displayLocation(final StringBuffer html, final Location location, final int nodeLevel,
            final List<Location> allLocations) {
        String selectStr = "";
        if (selected != null) {
            if (location.getId().equals(new Long(selected))) {
                selectStr = "SELECTED";
            }
        }
        html.append("<option value=\"" + location.getId() + "\" " + selectStr + ">"
                + getIndentedName(nodeLevel, location) + "</option>");
        displayChildren(html, location, nodeLevel, allLocations);
    }

    private void displayChildren(final StringBuffer html, final Location parentLocation, final int parentLevel,
            final List<Location> allLocations) {
        List<Location> children = CoreServiceLocator.getLocationService().findChildren(parentLocation);
        Collections.sort(children);
        Iterator<Location> iter = children.iterator();
        while (iter.hasNext()) {
            Location childLocation = iter.next();
            if (allLocations.contains(childLocation)) {
                displayLocation(html, childLocation, parentLevel + 1, allLocations);
            }
        }
    }

    private String getIndentedName(final int nodeLevel, final Location location) {
        log.debug("getIndentedName() - method to indent displayed location name in the combo box");
        String indentedName = "";

        if (showIndents.startsWith("tr")) {
            for (int i = 0; i < nodeLevel; i++) {
                indentedName += " -";
            }
        }
        indentedName += location.getName();
        log.debug("getIndentedName() - done");
        return indentedName;
    }

    /**
     * @return
     */
    public String getStyleClass() {
        return styleClass;
    }

    /**
     * @param styleClass
     */
    public void setStyleClass(final String styleClass) {
        this.styleClass = styleClass;
    }

    /**
     * @return
     */
    public String getProperty() {
        return property;
    }

    /**
     * @param property
     */
    public void setProperty(final String property) {
        this.property = property;
    }

    /**
     * @return
     */
    public String getSelected() {
        return selected;
    }

    /**
     * @param selected
     */
    public void setSelected(final String selected) {
        this.selected = selected;
    }

    /**
     * @return Returns the none.
     */
    public String getNone() {
        return none;
    }

    /**
     * @param none
     *            The none to set.
     */
    public void setNone(final String none) {
        this.none = none;
    }

    /**
     * @return Returns the domainId.
     */
    public String getDomainId() {
        return domainId;
    }

    /**
     * @param domainId
     *            The domainId to set.
     */
    public void setDomainId(final String domainId) {
        if (domainId.startsWith("311")) {
            this.domainId = domainId.substring(3);

        } else {
            this.domainId = domainId;
        }
    }

    public Domain getDomain() {
        Domain domain = null;
        if (StringUtils.isNullOrBlank(getDomainId()) == false) {
            domain = CoreServiceLocator.getSystemService().findDomain(new Long(getDomainId()));
        }
        if (domain == null) {
            domain = ThreadProperties.getDomain();
        }
        return domain;
    }

    /**
     * @return Returns the locationType.
     */
    public String getLocationType() {
        return locationType;
    }

    /**
     * @param locationType
     *            The locationType to set.
     */
    public void setLocationType(final String locationType) {
        this.locationType = locationType;
    }

}
